package edu.ynu.se.xiecheng.achitectureclass.service;

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Service
public class FboxService {

    public static final String FBOX_LOGIN_URL = "https://fbox360.com/idserver/core/connect/token";
    private static final String CLIENT_ID = "68db2e8bda8d47b5b5db7eaf71c7dcdd";
    private static final String CLIENT_SECRET = "76dc724c95004acab25482d344dab407";
    private static final String SCOPE = "fbox";
    private static final String GRANT_TYPE = "client_credentials";

    // 使用 volatile 确保多线程环境下的可见性
    private volatile String accessToken;
    private volatile Long accessTokenExpiresAt;

    private final RestTemplate restTemplate;

    public FboxService(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
    }

    /**
     * 获取 accessToken（带缓存和线程安全）
     */
    public String getAccessToken() {
        // 检查 Token 是否已过期
        if (accessToken == null || System.currentTimeMillis() >= accessTokenExpiresAt) {
            synchronized (this) {
                // 双重检查锁，避免多个线程同时刷新 Token
                if (accessToken == null || System.currentTimeMillis() >= accessTokenExpiresAt) {
                    refreshAccessToken();
                }
            }
        }
        return accessToken;
    }

    /**
     * 刷新 accessToken
     */
    private void refreshAccessToken() {
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("scope", SCOPE);
        params.add("client_id", CLIENT_ID);
        params.add("client_secret", CLIENT_SECRET);
        params.add("grant_type", GRANT_TYPE);

        ResponseEntity<FboxTokenResponse> response = restTemplate.postForEntity(FBOX_LOGIN_URL, params, FboxTokenResponse.class);

        if (response.getStatusCode().is2xxSuccessful()) {
            FboxTokenResponse tokenResponse = response.getBody();
            if (tokenResponse != null) {
                accessToken = tokenResponse.getAccessToken();
                accessTokenExpiresAt = System.currentTimeMillis() + (tokenResponse.getExpiresIn() * 1000L);
                System.out.println("Refreshed accessToken: " + accessToken);
            }
        } else {
            throw new RuntimeException("Failed to obtain accessToken from fbox.");
        }
    }
}